﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using SimpleBlog.Infrastructure.Repositories;
using SimpleBlog.Models;
using SimpleBlog.Infrastructure.Database;

namespace SimpleBlog.Infrastructure
{
    public class SbResolver : IDependencyResolver
    {
        private UnityContainer container;

        public SbResolver()
        {
            this.container = new UnityContainer();

            //Instances to register
            SbContext context = new SbContext();
            IConfigurationRepository configurationRepository = new ConfigurationRepository(context);

            //Database context singleton registration
            this.container.RegisterInstance(context);
            this.container.RegisterInstance<IConfigurationRepository>(configurationRepository);

            //Repositories registration
            this.container.RegisterType<IPostRepository, PostRepository>();
            this.container.RegisterType<IUserRepository, UserRepository>();
            this.container.RegisterType<ITagRepository, TagRepository>();
            this.container.RegisterType<ICommentRepository, CommentRepository>();

            //Register all controller type found in current assembly to the Unity container will be able to resolve them
            foreach (Type controllerType in (from t in Assembly.GetExecutingAssembly().GetTypes() where typeof(IController).IsAssignableFrom(t) select t))
            {
                this.container.RegisterType(controllerType);
            }
        }

        public object GetService(Type serviceType)
        {
            //
            //  Unity "Resolve" method throws exception so we need to wrap it up with non throwing method (like MVC expects)
            //
            return TryGetService(serviceType);
        }

        public object TryGetService(Type serviceType)
        {
            try
            {
                return this.container.Resolve(serviceType);
            }
            catch (Exception)
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            //
            //  Unity "Resolve" method throws exception so we need to wrap it up with non throwing method (like MVC expects)
            //
            return TryGetServices(serviceType);
        }

        public IEnumerable<object> TryGetServices(Type serviceType)
        {
            try
            {
                return this.container.ResolveAll(serviceType);
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
}